﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Collections;

namespace SP.Docs.Migrator
{
    public partial class frmMoveDocs : Form
    {
        public frmMoveDocs()
        {
            InitializeComponent();
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            Close();
        }
        private void RestoreProperties(Hashtable source, Hashtable dest)
        {
            foreach (System.Collections.DictionaryEntry prop in source)
            {
                try
                {
                    dest[prop.Key] = prop.Value;
                }
                catch { }
            }
        }
        private void ArchivingProcess()
        {
            try
            {
                // Archive();
                PostMessage("Process started, attempting to escalate the privileges");
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    PostMessage("Permissions escalated, connecting to connect the site: " + txtSource.Text);
                    using (SPSite site = new SPSite(txtSource.Text))
                    {
                        PostMessage("Site connected : " + txtSource.Text);
                        PostMessage("Attempting to open web");
                        using (SPWeb web = site.OpenWeb())
                        {
                            PostMessage("Web opened");
                            PostMessage("Attempting to load source files");
                            SPFileCollection sourceFiles = null;
                            try
                            {
                                sourceFiles = web.Folders[txtSource.Text + "/" + lstSourceLib.Text].Files;
                            }
                            catch 
                            {
                                SPList lst = web.Lists[lstSourceLib.Text];
                                sourceFiles = lst.RootFolder.Files;
                            }
                            PostMessage("Total source files found: " + sourceFiles.Count);
                            PostMessage("Attempting to connect the destination site: " + txtDestination.Text);
                            using (SPSite targetSite = new SPSite(txtDestination.Text))
                            {
                                PostMessage("Destination site connected: " + txtDestination.Text);
                                PostMessage("Attempting to open the web: " + txtDestination.Text);
                                using (SPWeb targetWeb = targetSite.OpenWeb())
                                {
                                    SPList list= targetWeb.Lists[lstSourceLib.Text];
                                    foreach(SPListItem item in list.Items)
                                    {
                                        
                                        SPFieldText field = new SPFieldText(item.Versions[0].Fields, SPFieldType.Text.ToString(), "State");
                                    }
                                    PostMessage("Web opened");
                                    PostMessage("Loading destination folders");
                                    SPFileCollection targetFiles = null;
                                    try
                                    {
                                        targetFiles = targetWeb.Folders[txtDestination.Text + "/" + lstDestLib.Text].Files;
                                    }
                                    catch(Exception ex) 
                                    {
                                        SPList lst = web.Lists[lstDestLib.Text];
                                        targetFiles = lst.RootFolder.Files;
                                    }
                                    PostMessage("Total destination files: " + targetFiles.Count);
                                    string temp1 = txtSource.Text + "/" + lstSourceLib.Text;
                                    string temp2 = txtDestination.Text + "/" + lstDestLib.Text;
                                    byte[] binFrom = null;
                                    PostMessage("Iterating the source files");
                                    SetProgressBar(sourceFiles.Count);
                                    List<SPFile> ArchivedFiles = new List<SPFile>();
                                    for (int i = 0; i < sourceFiles.Count; i++)
                                    {
                                        try
                                        {
                                            SPFile newFile = null;
                                            SPFile sourceFile = sourceFiles[sourceFiles.Count - i - 1];

                                            SetProgress(i + 1);
                                            PostMessage("Processing file: " + sourceFile.Name);
                                            PostMessage("Processing versions for: " + sourceFile.Name);
                                            foreach (SPFileVersion version in sourceFile.Versions)
                                            {
                                                try
                                                {
                                                    binFrom = version.OpenBinary();
                                                    DateTime creationDate = version.Created.ToLocalTime();
                                                    newFile = targetFiles.Add(sourceFile.Url.Replace(lstSourceLib.Text, lstDestLib.Text), binFrom, version.CreatedBy, version.CreatedBy, creationDate, creationDate);
                                                    newFile.Item["Created"] = creationDate;
                                                    newFile.Item["Modified"] = creationDate;

                                                    RestoreProperties(version.Properties, newFile.Item.Properties);
                                                    
                                                    newFile.Item.UpdateOverwriteVersion();
                                                    PostMessage("Version processed : " + version.Url);
                                                }
                                                catch { }
                                            }
                                            PostMessage("Versions archived");
                                            PostMessage("Archiving orignal file");
                                            binFrom = sourceFile.OpenBinary();
                                            SPUser user = sourceFile.ModifiedBy == null ? web.CurrentUser : sourceFile.ModifiedBy;


                                            newFile = targetFiles.Add(sourceFile.Url.Replace(lstSourceLib.Text, lstDestLib.Text), binFrom, user, user, sourceFile.TimeCreated.ToLocalTime(), sourceFile.TimeLastModified.ToLocalTime());

                                            newFile.Item["Created"] = sourceFile.Item["Created"];
                                            newFile.Item["Modified"] = sourceFile.Item["Modified"];

                                            RestoreProperties(sourceFile.Item.Properties, newFile.Item.Properties);

                                            newFile.Item.UpdateOverwriteVersion();
                                            PostMessage("Orignal file archived");
                                            if(chkDeleteFile.Checked)
                                                ArchivedFiles.Add(sourceFile);
                                        }
                                        catch { }
                                    }
                                    if (chkDeleteFile.Checked)
                                    {
                                        PostMessage("Deleting archived files from the source");
                                        foreach (SPFile file in ArchivedFiles)
                                        {
                                            PostMessage("Deleting file: " + file.Name);
                                            file.Delete();
                                        }
                                    }
                                }
                            }
                        }
                    }
                });
            }
            catch (Exception ex) { PostMessage("Exception Occured : " + ex.Message); }
            finally { PostMessage("Operation finished!"); }
        }
        private void SetProgressBar(int count)
        {
            progressBar1.Maximum = count;
            progressBar1.Update();
        }
        private void SetProgress(int val)
        {
            progressBar1.Value = val;
            progressBar1.Update();
        }
        private void btnArchive_Click(object sender, EventArgs e)
        {
            System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(ArchivingProcess));
            thread.Start();
            //ArchivingProcess();
        }
        private void PostMessage(string msg)
        {
            lstOperationLog.Items.Add(msg);
            lstOperationLog.Update();
        }
        private string[] RetrieveLists(string siteUrl)
        {
            System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;
            try
            {
                using (SPSite site = new SPSite(siteUrl))
                {
                    using (SPWeb web = site.OpenWeb())
                    {
                        string[] names = new string[web.Lists.Count];
                        for (int i = 0; i < web.Lists.Count; i++)
                        {
                            names[i] = web.Lists[i].Title;
                        }
                        return (names);
                    }
                }
            }
            catch { }
            finally 
            {
                System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default;
            }
            return (null);
        }
        private void btnBrowse1_Click(object sender, EventArgs e)
        {
            lstSourceLib.DataSource = RetrieveLists(txtSource.Text);
        }

        private void btnBrowse2_Click(object sender, EventArgs e)
        {
            lstDestLib.DataSource = RetrieveLists(txtDestination.Text);
        }

        private void frmArchive_Load(object sender, EventArgs e)
        {

        }

        private void frmArchive_FormClosed(object sender, FormClosedEventArgs e)
        {
            //Close();
        }
    }
}
